package com.dongnaoedu.rpc.redis.support;

import java.lang.reflect.Method;

import org.springframework.util.ClassUtils;

import com.dongnaoedu.rpc.redis.Channel;

import io.lettuce.core.dynamic.support.ReflectionUtils;

public abstract class AbstractChannelSupport implements Channel {

	private final Class<?> clazz;

	private final Method method;

	private final Class<?>[] paramTypes;
	
	public AbstractChannelSupport(String _interface, String _method, Object[] args) {
		this._interface = _interface;
		this._method = _method;
		this.args = args;
		this.clazz = findClass();
		this.paramTypes = findParamTypes();
		this.method = ReflectionUtils.findMethod(this.clazz, _method, paramTypes);
	}

	private Class<?>[] findParamTypes() {
		Class<?>[] paramTypes = new Class<?>[args.length];
		for (int i = 0; i < args.length; i++) {
			paramTypes[i] = args[i].getClass();
		}
		return paramTypes;
	}

	private Class<?> findClass() {
		Class<?> cl = null;
		try {
			cl = ClassUtils.forName(_interface, Thread.currentThread().getContextClassLoader());
		} catch (ClassNotFoundException | LinkageError e) {
			throw new RuntimeException(_interface + " is not found.");
		} 
		if(!cl.isInterface()) {
			throw new RuntimeException(_interface + " is not interface.");
		}
		return cl;
	}

	@Override
	public Class<?> getInterface() {
		return this.clazz;
	}

	@Override
	public Method getMethod() {
		return this.method;
	}

	@Override
	public Class<?>[] getParamTypes() {
		return this.paramTypes;
	}
	
	public abstract Type getType();

	private final String _interface;
	private final String _method;
	private final Object[] args;

	public String getInterfaceClass() {
		return this._interface;
	}

	public String getMethodName() {
		return this._method;
	}
	
	@Override
	public Object[] getArgs() {
		return this.args;
	}

}
